<?php


namespace link\hefang\cms\application\content\controllers;


use link\hefang\cms\application\content\models\ArticleModel;
use link\hefang\cms\application\content\models\CommentModel;
use link\hefang\cms\application\user\models\AccountModel;
use link\hefang\cms\core\controllers\BaseCmsController;
use link\hefang\guid\GUKey;
use link\hefang\helpers\StringHelper;
use link\hefang\helpers\TimeHelper;
use link\hefang\mvc\databases\Sql;
use link\hefang\mvc\databases\SqlSort;
use link\hefang\mvc\exceptions\ModelException;
use link\hefang\mvc\exceptions\SqlException;
use link\hefang\mvc\Mvc;
use link\hefang\mvc\views\BaseView;
use Throwable;

class CommentController extends BaseCmsController
{
	/**
	 * @method POST
	 * @method PATCH
	 * @method PUT
	 * @param string|null $id
	 * @return BaseView
	 */
	public function set(string $id = null): BaseView
	{
		$login = $this->_checkLogin();
		if ($login->isLocked()) {
			return $this->_restApiLocked("您的账号已被锁定, 无法执行该操作");
		}
		$method = $this->_method();
		try {
			if ($method === "POST") {
				return $this->insert($login);
			} else {
				$model = CommentModel::get($id);
				if (!$model->isExist()) {
					return $this->_restApiNotFound();
				}
				$data = $this->_post();
				foreach ($data as $prop => $value) {
					$model->setValue2Prop($value, $prop);
				}
				$res = $model->update(["content", "read_time"]);
				return $res ? $this->_restApiOk($res) : $this->_restNotModified($res);
			}
		} catch (Throwable $e) {
			return $this->_restApiServerError($e);
		}
	}

	/**
	 * @param AccountModel $login
	 * @return BaseView
	 * @throws ModelException
	 * @throws SqlException
	 */
	private function insert(AccountModel $login): BaseView
	{
		$data = $this->_post();
		foreach (["contentId", "content"] as $prop) {
			if (!isset($data[$prop])) {
				return $this->_restApiBadRequest("请求参数不正确: $prop");
			}
		}
		$article = ArticleModel::get($data["contentId"]);

		if (!$article->isExist() || !$article->isEnable() || $article->isDraft()) {
			return $this->_restApiNotFound("要评论的内容不存在, 已删除或未发表");
		}

		$key = new GUKey(CommentModel::class);
		$model = new CommentModel();
		if (!StringHelper::isNullOrEmpty($data["replayId"])) {
			$replay = CommentModel::get($data["replayId"]);
			if (!$replay->isExist() || !$replay->isEnable()) {
				return $this->_restApiNotFound("要回复的评论不存在或已删除");
			}
			$model->setReplayId($replay->getId());
		}
		$res = $model
			->setId($key->next())
			->setContentId($article->getId())
			->setAuthorId($login->getId())
			->setContent($data["content"])
			->setFloor(CommentModel::database()->max(
				CommentModel::table(),
				"floor",
				new Sql("`content_id`=:contentId", [
					"contentId" => $article->getId()
				])
			))
			->setPostTime(TimeHelper::formatMillis())
			->insert();
		return $res ? $this->_restApiOk($model) : $this->_restFailedUnknownReason($res);
	}

	public function list(string $cmd = null): BaseView
	{
		if (strcasecmp($cmd, "unread") == 0) {
			return $this->unread();
		}
		return parent::list($cmd); // TODO: Change the autogenerated stub
	}

	private function unread(): BaseView
	{
		$login = $this->_checkLogin();
		try {
			$tablePrefix = Mvc::getTablePrefix();
			$pager = CommentModel::pager(
				1, 10,
				new Sql(
					"`read_time` IS NULL AND `content_id` IN (SELECT `id` FROM `{$tablePrefix}article` WHERE author_id=:authorId)",
					[
						"authorId" => $login->getId()
					]
				),
				[new SqlSort("postTime")]
			);
			return $this->_restApiOk($pager);
		} catch (Throwable $e) {
			return $this->_restApiServerError($e);
		}
	}
}
